#include <stdio.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>

//定义两个参数，用来记录目录个数 和 文件个数
int directories = 0;
int files = 0;
//参数为文件内容，和要进行缩进的长度
void dfs_print(const char* path, int length);
int main(int argc, char* argv[])
{
    // ./tree dir
    //参数校验
    if(argc != 2)
    {
        error(1, 0, "Usage : %s dir", argv[0]);
    }
    //整体的思路是  先打印根节点在，递归的遍历子树，可以看做先序遍历
    //遍历根节点
    puts(argv[1]);
    //递归的遍历每个子树
    dfs_print(argv[1], 4);
    
    printf("\n%d directories, %d files\n", directories, files);
    return 0;
}

void dfs_print(const char* path, int length)
{
    // //打开成功,遍历每个目录项
    // int errno = 0;
    // 传进来的参数是文件路径
    // 先打开文件目录
    DIR* stream = opendir(path);
    //查看是否打开成功
    //返回空 说明打开失败
    if(!stream)
    {
        error(1, errno, "opendir");
    }

    errno = 0;
    struct dirent* pdirent;
    while((pdirent = readdir(stream)) != NULL)
    {
        char* filename = pdirent->d_name;
        //忽略 . 和 .. 如果是. 或者 .. 就跳过
        if(strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
        {
            continue;
        }
        //打印当前目录项
        for(int i = 0; i < length; i++)
        {
            putchar(' ');
        }
        puts(filename);
        //如果为 文件夹就拼接路径
        if(pdirent->d_type == DT_DIR)
        {
            directories++;
            //拼接路径
            char subpath[1024];
            //在全进来的路径后面加实现拼接路径的效果
            snprintf(subpath, sizeof(subpath),"%s/%s", path, filename);
            dfs_print(subpath, length+4);
        }
        else{
            files++;
        }
        
    }
    closedir(stream);
    if(errno)
    {
        error(1, errno, "readdir");
    }
}
